home *** CD-ROM | disk | FTP | other *** search
/ Clickx 47 / Clickx 47.iso / assets / software / Miro_Installer.exe / Miro_Downloader.exe / profile.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2008-01-10  |  15.5 KB  |  512 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''Class for profiling Python code.'''
  5. import sys
  6. import os
  7. import time
  8. import marshal
  9. from optparse import OptionParser
  10. __all__ = [
  11.     'run',
  12.     'runctx',
  13.     'help',
  14.     'Profile']
  15.  
  16. def run(statement, filename = None, sort = -1):
  17.     '''Run statement under profiler optionally saving results in filename
  18.  
  19.     This function takes a single argument that can be passed to the
  20.     "exec" statement, and an optional file name.  In all cases this
  21.     routine attempts to "exec" its first argument and gather profiling
  22.     statistics from the execution. If no file name is present, then this
  23.     function automatically prints a simple profiling report, sorted by the
  24.     standard name string (file/line/function-name) that is presented in
  25.     each line.
  26.     '''
  27.     prof = Profile()
  28.     
  29.     try:
  30.         prof = prof.run(statement)
  31.     except SystemExit:
  32.         pass
  33.  
  34.     if filename is not None:
  35.         prof.dump_stats(filename)
  36.     else:
  37.         return prof.print_stats(sort)
  38.  
  39.  
  40. def runctx(statement, globals, locals, filename = None):
  41.     '''Run statement under profiler, supplying your own globals and locals,
  42.     optionally saving results in filename.
  43.  
  44.     statement and filename have the same semantics as profile.run
  45.     '''
  46.     prof = Profile()
  47.     
  48.     try:
  49.         prof = prof.runctx(statement, globals, locals)
  50.     except SystemExit:
  51.         pass
  52.  
  53.     if filename is not None:
  54.         prof.dump_stats(filename)
  55.     else:
  56.         return prof.print_stats()
  57.  
  58.  
  59. def help():
  60.     print 'Documentation for the profile module can be found '
  61.     print "in the Python Library Reference, section 'The Python Profiler'."
  62.  
  63. if os.name == 'mac':
  64.     import MacOS
  65.     
  66.     def _get_time_mac(timer = MacOS.GetTicks):
  67.         return timer() / 60
  68.  
  69.  
  70. if hasattr(os, 'times'):
  71.     
  72.     def _get_time_times(timer = os.times):
  73.         t = timer()
  74.         return t[0] + t[1]
  75.  
  76.  
  77. _has_res = 0
  78.  
  79. try:
  80.     import resource
  81.     
  82.     resgetrusage = lambda : resource.getrusage(resource.RUSAGE_SELF)
  83.     
  84.     def _get_time_resource(timer = resgetrusage):
  85.         t = timer()
  86.         return t[0] + t[1]
  87.  
  88.     _has_res = 1
  89. except ImportError:
  90.     pass
  91.  
  92.  
  93. class Profile:
  94.     '''Profiler class.
  95.  
  96.     self.cur is always a tuple.  Each such tuple corresponds to a stack
  97.     frame that is currently active (self.cur[-2]).  The following are the
  98.     definitions of its members.  We use this external "parallel stack" to
  99.     avoid contaminating the program that we are profiling. (old profiler
  100.     used to write into the frames local dictionary!!) Derived classes
  101.     can change the definition of some entries, as long as they leave
  102.     [-2:] intact (frame and previous tuple).  In case an internal error is
  103.     detected, the -3 element is used as the function name.
  104.  
  105.     [ 0] = Time that needs to be charged to the parent frame\'s function.
  106.            It is used so that a function call will not have to access the
  107.            timing data for the parent frame.
  108.     [ 1] = Total time spent in this frame\'s function, excluding time in
  109.            subfunctions (this latter is tallied in cur[2]).
  110.     [ 2] = Total time spent in subfunctions, excluding time executing the
  111.            frame\'s function (this latter is tallied in cur[1]).
  112.     [-3] = Name of the function that corresponds to this frame.
  113.     [-2] = Actual frame that we correspond to (used to sync exception handling).
  114.     [-1] = Our parent 6-tuple (corresponds to frame.f_back).
  115.  
  116.     Timing data for each function is stored as a 5-tuple in the dictionary
  117.     self.timings[].  The index is always the name stored in self.cur[-3].
  118.     The following are the definitions of the members:
  119.  
  120.     [0] = The number of times this function was called, not counting direct
  121.           or indirect recursion,
  122.     [1] = Number of times this function appears on the stack, minus one
  123.     [2] = Total time spent internal to this function
  124.     [3] = Cumulative time that this function was present on the stack.  In
  125.           non-recursive functions, this is the total execution time from start
  126.           to finish of each invocation of a function, including time spent in
  127.           all subfunctions.
  128.     [4] = A dictionary indicating for each function name, the number of times
  129.           it was called by us.
  130.     '''
  131.     bias = 0
  132.     
  133.     def __init__(self, timer = None, bias = None):
  134.         self.timings = { }
  135.         self.cur = None
  136.         self.cmd = ''
  137.         self.c_func_name = ''
  138.         if bias is None:
  139.             bias = self.bias
  140.         
  141.         self.bias = bias
  142.         if not timer:
  143.             if _has_res:
  144.                 self.timer = resgetrusage
  145.                 self.dispatcher = self.trace_dispatch
  146.                 self.get_time = _get_time_resource
  147.             elif os.name == 'mac':
  148.                 self.timer = MacOS.GetTicks
  149.                 self.dispatcher = self.trace_dispatch_mac
  150.                 self.get_time = _get_time_mac
  151.             elif hasattr(time, 'clock'):
  152.                 self.timer = self.get_time = time.clock
  153.                 self.dispatcher = self.trace_dispatch_i
  154.             elif hasattr(os, 'times'):
  155.                 self.timer = os.times
  156.                 self.dispatcher = self.trace_dispatch
  157.                 self.get_time = _get_time_times
  158.             else:
  159.                 self.timer = self.get_time = time.time
  160.                 self.dispatcher = self.trace_dispatch_i
  161.         else:
  162.             self.timer = timer
  163.             t = self.timer()
  164.             
  165.             try:
  166.                 length = len(t)
  167.             except TypeError:
  168.                 self.get_time = timer
  169.                 self.dispatcher = self.trace_dispatch_i
  170.  
  171.             if length == 2:
  172.                 self.dispatcher = self.trace_dispatch
  173.             else:
  174.                 self.dispatcher = self.trace_dispatch_l
  175.             
  176.             def get_time_timer(timer = timer, sum = sum):
  177.                 return sum(timer())
  178.  
  179.             self.get_time = get_time_timer
  180.         self.t = self.get_time()
  181.         self.simulate_call('profiler')
  182.  
  183.     
  184.     def trace_dispatch(self, frame, event, arg):
  185.         timer = self.timer
  186.         t = timer()
  187.         t = t[0] + t[1] - self.t - self.bias
  188.         if event == 'c_call':
  189.             self.c_func_name = arg.__name__
  190.         
  191.         if self.dispatch[event](self, frame, t):
  192.             t = timer()
  193.             self.t = t[0] + t[1]
  194.         else:
  195.             r = timer()
  196.             self.t = r[0] + r[1] - t
  197.  
  198.     
  199.     def trace_dispatch_i(self, frame, event, arg):
  200.         timer = self.timer
  201.         t = timer() - self.t - self.bias
  202.         if event == 'c_call':
  203.             self.c_func_name = arg.__name__
  204.         
  205.         if self.dispatch[event](self, frame, t):
  206.             self.t = timer()
  207.         else:
  208.             self.t = timer() - t
  209.  
  210.     
  211.     def trace_dispatch_mac(self, frame, event, arg):
  212.         timer = self.timer
  213.         t = timer() / 60 - self.t - self.bias
  214.         if event == 'c_call':
  215.             self.c_func_name = arg.__name__
  216.         
  217.         if self.dispatch[event](self, frame, t):
  218.             self.t = timer() / 60
  219.         else:
  220.             self.t = timer() / 60 - t
  221.  
  222.     
  223.     def trace_dispatch_l(self, frame, event, arg):
  224.         get_time = self.get_time
  225.         t = get_time() - self.t - self.bias
  226.         if event == 'c_call':
  227.             self.c_func_name = arg.__name__
  228.         
  229.         if self.dispatch[event](self, frame, t):
  230.             self.t = get_time()
  231.         else:
  232.             self.t = get_time() - t
  233.  
  234.     
  235.     def trace_dispatch_exception(self, frame, t):
  236.         (rpt, rit, ret, rfn, rframe, rcur) = self.cur
  237.         if rframe is not frame and rcur:
  238.             return self.trace_dispatch_return(rframe, t)
  239.         
  240.         self.cur = (rpt, rit + t, ret, rfn, rframe, rcur)
  241.         return 1
  242.  
  243.     
  244.     def trace_dispatch_call(self, frame, t):
  245.         if self.cur and frame.f_back is not self.cur[-2]:
  246.             (rpt, rit, ret, rfn, rframe, rcur) = self.cur
  247.             if not isinstance(rframe, Profile.fake_frame):
  248.                 if not rframe.f_back is frame.f_back:
  249.                     raise AssertionError, ('Bad call', rfn, rframe, rframe.f_back, frame, frame.f_back)
  250.                 self.trace_dispatch_return(rframe, 0)
  251.                 if not self.cur is None and frame.f_back is self.cur[-2]:
  252.                     raise AssertionError, ('Bad call', self.cur[-3])
  253.             
  254.         
  255.         fcode = frame.f_code
  256.         fn = (fcode.co_filename, fcode.co_firstlineno, fcode.co_name)
  257.         self.cur = (t, 0, 0, fn, frame, self.cur)
  258.         timings = self.timings
  259.         if fn in timings:
  260.             (cc, ns, tt, ct, callers) = timings[fn]
  261.             timings[fn] = (cc, ns + 1, tt, ct, callers)
  262.         else:
  263.             timings[fn] = (0, 0, 0, 0, { })
  264.         return 1
  265.  
  266.     
  267.     def trace_dispatch_c_call(self, frame, t):
  268.         fn = ('', 0, self.c_func_name)
  269.         self.cur = (t, 0, 0, fn, frame, self.cur)
  270.         timings = self.timings
  271.         if timings.has_key(fn):
  272.             (cc, ns, tt, ct, callers) = timings[fn]
  273.             timings[fn] = (cc, ns + 1, tt, ct, callers)
  274.         else:
  275.             timings[fn] = (0, 0, 0, 0, { })
  276.         return 1
  277.  
  278.     
  279.     def trace_dispatch_return(self, frame, t):
  280.         if frame is not self.cur[-2]:
  281.             if not frame is self.cur[-2].f_back:
  282.                 raise AssertionError, ('Bad return', self.cur[-3])
  283.             self.trace_dispatch_return(self.cur[-2], 0)
  284.         
  285.         (rpt, rit, ret, rfn, frame, rcur) = self.cur
  286.         rit = rit + t
  287.         frame_total = rit + ret
  288.         (ppt, pit, pet, pfn, pframe, pcur) = rcur
  289.         self.cur = (ppt, pit + rpt, pet + frame_total, pfn, pframe, pcur)
  290.         timings = self.timings
  291.         (cc, ns, tt, ct, callers) = timings[rfn]
  292.         if not ns:
  293.             ct = ct + frame_total
  294.             cc = cc + 1
  295.         
  296.         if pfn in callers:
  297.             callers[pfn] = callers[pfn] + 1
  298.         else:
  299.             callers[pfn] = 1
  300.         timings[rfn] = (cc, ns - 1, tt + rit, ct, callers)
  301.         return 1
  302.  
  303.     dispatch = {
  304.         'call': trace_dispatch_call,
  305.         'exception': trace_dispatch_exception,
  306.         'return': trace_dispatch_return,
  307.         'c_call': trace_dispatch_c_call,
  308.         'c_exception': trace_dispatch_return,
  309.         'c_return': trace_dispatch_return }
  310.     
  311.     def set_cmd(self, cmd):
  312.         if self.cur[-1]:
  313.             return None
  314.         
  315.         self.cmd = cmd
  316.         self.simulate_call(cmd)
  317.  
  318.     
  319.     class fake_code:
  320.         
  321.         def __init__(self, filename, line, name):
  322.             self.co_filename = filename
  323.             self.co_line = line
  324.             self.co_name = name
  325.             self.co_firstlineno = 0
  326.  
  327.         
  328.         def __repr__(self):
  329.             return repr((self.co_filename, self.co_line, self.co_name))
  330.  
  331.  
  332.     
  333.     class fake_frame:
  334.         
  335.         def __init__(self, code, prior):
  336.             self.f_code = code
  337.             self.f_back = prior
  338.  
  339.  
  340.     
  341.     def simulate_call(self, name):
  342.         code = self.fake_code('profile', 0, name)
  343.         if self.cur:
  344.             pframe = self.cur[-2]
  345.         else:
  346.             pframe = None
  347.         frame = self.fake_frame(code, pframe)
  348.         self.dispatch['call'](self, frame, 0)
  349.  
  350.     
  351.     def simulate_cmd_complete(self):
  352.         get_time = self.get_time
  353.         t = get_time() - self.t
  354.         while self.cur[-1]:
  355.             self.dispatch['return'](self, self.cur[-2], t)
  356.             t = 0
  357.         self.t = get_time() - t
  358.  
  359.     
  360.     def print_stats(self, sort = -1):
  361.         import pstats
  362.         pstats.Stats(self).strip_dirs().sort_stats(sort).print_stats()
  363.  
  364.     
  365.     def dump_stats(self, file):
  366.         f = open(file, 'wb')
  367.         self.create_stats()
  368.         marshal.dump(self.stats, f)
  369.         f.close()
  370.  
  371.     
  372.     def create_stats(self):
  373.         self.simulate_cmd_complete()
  374.         self.snapshot_stats()
  375.  
  376.     
  377.     def snapshot_stats(self):
  378.         self.stats = { }
  379.         for cc, ns, tt, ct, callers in self.timings.iteritems():
  380.             callers = callers.copy()
  381.             nc = 0
  382.             for callcnt in callers.itervalues():
  383.                 nc += callcnt
  384.             
  385.             self.stats[func] = (cc, nc, tt, ct, callers)
  386.         
  387.  
  388.     
  389.     def run(self, cmd):
  390.         import __main__
  391.         dict = __main__.__dict__
  392.         return self.runctx(cmd, dict, dict)
  393.  
  394.     
  395.     def runctx(self, cmd, globals, locals):
  396.         self.set_cmd(cmd)
  397.         sys.setprofile(self.dispatcher)
  398.         
  399.         try:
  400.             exec cmd in globals, locals
  401.         finally:
  402.             sys.setprofile(None)
  403.  
  404.         return self
  405.  
  406.     
  407.     def runcall(self, func, *args, **kw):
  408.         self.set_cmd(repr(func))
  409.         sys.setprofile(self.dispatcher)
  410.         
  411.         try:
  412.             return func(*args, **kw)
  413.         finally:
  414.             sys.setprofile(None)
  415.  
  416.  
  417.     
  418.     def calibrate(self, m, verbose = 0):
  419.         if self.__class__ is not Profile:
  420.             raise TypeError('Subclasses must override .calibrate().')
  421.         
  422.         saved_bias = self.bias
  423.         self.bias = 0
  424.         
  425.         try:
  426.             return self._calibrate_inner(m, verbose)
  427.         finally:
  428.             self.bias = saved_bias
  429.  
  430.  
  431.     
  432.     def _calibrate_inner(self, m, verbose):
  433.         get_time = self.get_time
  434.         
  435.         def f1(n):
  436.             for i in range(n):
  437.                 x = 1
  438.             
  439.  
  440.         
  441.         def f(m, f1 = f1):
  442.             for i in range(m):
  443.                 f1(100)
  444.             
  445.  
  446.         f(m)
  447.         t0 = get_time()
  448.         f(m)
  449.         t1 = get_time()
  450.         elapsed_noprofile = t1 - t0
  451.         if verbose:
  452.             print 'elapsed time without profiling =', elapsed_noprofile
  453.         
  454.         p = Profile()
  455.         t0 = get_time()
  456.         p.runctx('f(m)', globals(), locals())
  457.         t1 = get_time()
  458.         elapsed_profile = t1 - t0
  459.         if verbose:
  460.             print 'elapsed time with profiling =', elapsed_profile
  461.         
  462.         total_calls = 0
  463.         reported_time = 0
  464.         for filename, line, funcname in p.timings.items():
  465.             (cc, ns, tt, ct, callers) = None
  466.             if funcname in ('f', 'f1'):
  467.                 total_calls += cc
  468.                 reported_time += tt
  469.                 continue
  470.         
  471.         if verbose:
  472.             print "'CPU seconds' profiler reported =", reported_time
  473.             print 'total # calls =', total_calls
  474.         
  475.         if total_calls != m + 1:
  476.             raise ValueError('internal error: total calls = %d' % total_calls)
  477.         
  478.         mean = (reported_time - elapsed_noprofile) / 2 / total_calls
  479.         if verbose:
  480.             print 'mean stopwatch overhead per profile event =', mean
  481.         
  482.         return mean
  483.  
  484.  
  485.  
  486. def Stats(*args):
  487.     print 'Report generating functions are in the "pstats" module\x07'
  488.  
  489.  
  490. def main():
  491.     usage = 'profile.py [-o output_file_path] [-s sort] scriptfile [arg] ...'
  492.     parser = OptionParser(usage = usage)
  493.     parser.allow_interspersed_args = False
  494.     parser.add_option('-o', '--outfile', dest = 'outfile', help = 'Save stats to <outfile>', default = None)
  495.     parser.add_option('-s', '--sort', dest = 'sort', help = 'Sort order when printing to stdout, based on pstats.Stats class', default = -1)
  496.     if not sys.argv[1:]:
  497.         parser.print_usage()
  498.         sys.exit(2)
  499.     
  500.     (options, args) = parser.parse_args()
  501.     sys.argv[:] = args
  502.     if len(sys.argv) > 0:
  503.         sys.path.insert(0, os.path.dirname(sys.argv[0]))
  504.         run('execfile(%r)' % (sys.argv[0],), options.outfile, options.sort)
  505.     else:
  506.         parser.print_usage()
  507.     return parser
  508.  
  509. if __name__ == '__main__':
  510.     main()
  511.  
  512.